import { useState, useEffect, useImperativeHandle } from 'react';
import { Dropdown, Menu } from 'antd';
import { useLocation, useNavigate } from 'react-router-dom';
import { InbizIcon, isEditorENV, getDomainType, getDomain, useApp, singleTimeOut } from '@inbiz/utils';
import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import { arrayMoveImmutable } from 'array-move';
import { cloneDeep } from 'lodash';
import { observer } from '@formily/react';
import { useNowPageRoute } from '@inbiz/render';
import { TextWidget, getMessage } from '@inbiz/react';
import { extendApi, useEvents } from '@inbiz/utils';
import { getNameData } from '../servies';
import { routerPrefix } from 'InbizConfig';
import styles from './style.less';

const SortableList = SortableContainer((props: any) => (
  <div id="inbiz-tags-view-container" className={styles['inbiz-tags-view-container']}>
    <ul id="inbiz-tag-view-scroll">
      {props.children}
    </ul>
  </div>
)) as any;
const SortableItem = SortableElement((props: any) => props.children) as any;

const DragHandle: any = SortableHandle(() => (
  <>
    <InbizIcon type="icon-inbiz_other-drag" style={{ cursor: 'grab' }} />
  </>
));

const TagsView = observer((props: TagsViewProps) => {
  const { ref, emit, inbiz, callBackEvents, className, defaultBg, selectBg, actions, ...other } = props;
  const isRefresh = actions && actions.length > 0 ? true : false;
  const pageRoute = useNowPageRoute();
  const { aliveController } = inbiz?.appInfo;

  const [configEvents] = useEvents(callBackEvents, emit);

  // 站点信息
  const appInfo = useApp();
  // hash数据
  const location = useLocation();
  // histroy
  const history = useNavigate();
  // action按钮常量
  const ACTION_NAME = {
    CURRENT: 'current',
    OTHER: 'other',
    ALL: 'all',
  };
  // 是否是处于设计器环境
  const isEditor = isEditorENV();
  // 菜单cookie名,用于区分站点和端[web端|管理端]

  const menuCookieName = `${appInfo.userInfo.guid}-${getDomainType()}-${getDomain()}`;
  const defaultRouteArr = appInfo.SiteInfo.DefaultPageRoute.split('/');
  const defaultRoute = defaultRouteArr[defaultRouteArr.length - 1];

  const defaultIndexMenu = {
    key: defaultRoute,
    label: appInfo.SiteInfo.DefaultPageName,
    route: routerPrefix + appInfo.SiteInfo.DefaultPageRoute,
  };
  const cacheMenuData = sessionStorage.getItem(menuCookieName) || '[]';
  const cacheMenuDataArr = JSON.parse(cacheMenuData) || [];
  const defaultMenuData = cacheMenuDataArr.filter((item: any) => item.key != defaultIndexMenu.key);
  defaultMenuData.unshift(defaultIndexMenu);
  const [isTagsClick, $isTagsClick] = useState(false);
  const [currentMenu, $currentMenu] = useState(isEditor ? 'editorMenuItem' : '');
  const [currentIndex, $currentIndex] = useState(-1);
  const [menuData, $menuData] = useState<IMenu[]>(
    isEditor ? [{ key: 'editorMenuItem', label: '菜单页签' }] : defaultMenuData,
  );
  const [isShowUp, $isShowUp] = useState(false);

  const [isShowNext, $isShowNext] = useState(false);
  // menuData数据本地缓存
  const setMenuData = (data: any) => {
    if (!data) return;
    if (isEditor) return;
    $menuData(data);
    sessionStorage.setItem(menuCookieName, JSON.stringify(data))
  };

  useEffect(() => {
    if (isEditor) return;
    // 记录是否是页面
    // const routFix = process.env.NODE_ENV == 'development' ? '/preview/page/' : '/page/';
    // const isPage: boolean = location.pathname.indexOf(routFix) == 0;
    // if (isPage) return
    // 路由数组
    const pathSnippets: string[] = location.pathname.split('/').filter((i) => i);
    // 当前路由
    const routes: string[] = pathSnippets.slice(-1);
    const route: string = pageRoute ?? routes[0];
    // 查询路由对应名称Name
    getNameData({
      siteOutId: appInfo?.SiteInfo?.OutId || '',
      dataVersionId: appInfo?.DataVersionId || '',
      isPage: false,
      routes: [route],
    })
      .then((resData: any) => {
        if (!resData) return;
        let num = -1;
        menuData.forEach((item, index) => {
          if (item.key == route) {
            num = index;
          }
        });
        const res = resData['Item1'];
        const resRoutes = {
          key: route,
          label: res?.[route] ?? menuData?.[num].label ?? route,
          route: location.pathname,
        };
        $currentMenu(route);
        // menuData里已经存在该路由
        if (num > -1) {
          const data = cloneDeep(menuData);
          if (isTagsClick) {
            // 点击标签
            $currentIndex(num);
          } else {
            // 默认
            if (route == appInfo.SiteInfo.DefaultPageRoute || num == 0) {
              $currentIndex(0);
              jumpStart();
              return;
            }

            // 点击菜单
            $currentIndex(num);
            setMenuData(data);
            singleTimeOut(() => {
              jumpTo(data, num);
            }, 200, 'inbiz-tag-click')
          }
          $isTagsClick(false); // 复位状态
        } else {
          const data = [...menuData, resRoutes];
          $currentIndex(data.length - 1);
          setMenuData(data);
          singleTimeOut(() => {
            jumpTo(data, data.length - 1);
          }, 200, 'inbiz-tag-end')
        }
      })
      .catch(() => { });
  }, [location.pathname]);



  // 路由变更以及右侧关闭函数
  const changeRouter = (item: IMenu) => {
    if (item.key == ACTION_NAME.CURRENT) {
      // 关闭当前
      if (menuData.length == 1) return;
      let data = cloneDeep(menuData);
      let tmpItem: IMenu;
      for (let i = data.length - 1; i >= 0; i--) {
        if (data[i].key == currentMenu) {
          if (i == data.length - 1) {
            $currentIndex(0);
            jumpStart();
            tmpItem = data[0];
          } else {
            tmpItem = data[i + 1];
          }
          data.splice(i, 1);
          $currentMenu(tmpItem.key);
          if (tmpItem.route) {
            history(tmpItem.route);
          }
          break;
        }
      }
      setMenuData(data);
    } else if (item.key == ACTION_NAME.OTHER) {
      // 关闭其他
      if (menuData.length == 1) return;
      let data = cloneDeep(menuData);
      const cacheData = data.filter(
        (item) => item.key == currentMenu || item.key == defaultIndexMenu.key,
      );
      jumpStart();
      setMenuData(cacheData);
      $isShowUp(false);
      $isShowNext(false);
    } else if (item.key == ACTION_NAME.ALL) {
      // 关闭所有
      $currentIndex(0);
      jumpStart();
      $currentMenu(defaultIndexMenu.key);
      setMenuData([defaultIndexMenu]);
      $isShowUp(false);
      $isShowNext(false);
      if (defaultIndexMenu.route) {
        history(defaultIndexMenu.route);
      }
    } else {
      let num = -1;
      let route: string | undefined = '';
      menuData.forEach((menu, index) => {
        if (menu.key == item.key) {
          num = index;
          route = menu.route;
        }
      });
      if (num == -1) {
      } else {
        $currentIndex(num);
        $currentMenu(item.key);
        if (route) {
          history(route);
        }
      }
    }
    $isTagsClick(true);
  };


  // 关闭标签
  const handleClose = (item: IMenu, event: MouseEvent) => {
    event && event?.stopPropagation();
    closeByKey(item.key)
  };

  const closeByKey = (key?: string) => {
    if (menuData.length == 1) return;
    let data = cloneDeep(menuData);
    for (let i = data.length - 1; i >= 0; i--) {
      if (data[i].key == key) {
        // 选中后一个  1.菜单位于最后一项; 2.菜单位于其他位置
        let tmpItem: IMenu;
        if (key == currentMenu) {
          if (i == data.length - 1) {
            $currentIndex(0);
            jumpStart();
            tmpItem = data[0];
          } else {
            tmpItem = data[i + 1];
          }
          $currentMenu(tmpItem.key);
          if (tmpItem.route) {
            $isTagsClick(true); // 初始化为菜单标签点击状态
            history(tmpItem.route);
          }
        } else {
          if (key == data[data.length - 1].key || currentIndex == 0) {
            jumpStart();
          }
        }
        data.splice(i, 1);
        break;
      }
    }

    setMenuData(data);
  }

  // 拖拽
  const onSortEnd = ({ oldIndex, newIndex, collection }: any) => {
    if (oldIndex == newIndex) {
      changeRouter(collection)
    }
    if (newIndex == 0 || oldIndex == 0) {
      singleTimeOut(() => {
        jumpTo(menuData, oldIndex);
      }, 200, 'inbiz-tab-sortEnd')
      return;
    }
    if (oldIndex == currentIndex) {
      $currentIndex(newIndex);
    } else if (oldIndex > currentIndex && newIndex <= currentIndex) {
      $currentIndex((index) => index + 1);
    } else if (oldIndex < currentIndex && newIndex >= currentIndex) {
      $currentIndex((index) => index - 1);
    }

    const data = arrayMoveImmutable(menuData, oldIndex, newIndex);

    setMenuData(data);
    singleTimeOut(() => {
      jumpTo(data, newIndex);
    }, 200, 'inbiz-tab-sortEnd')
  };



  const jumpTo = (data: any[], currentNum: number) => {
    const elViewScroll = document.getElementById('inbiz-tag-view-scroll');
    const elTagViewContainer = document.getElementById('inbiz-tags-view-container');
    const scrollWidth = elViewScroll?.clientWidth || 0;
    const tagViewWidth = elTagViewContainer?.clientWidth || 0;

    let jumpWidth = 20;
    let nowCurrentWidth = 0;
    data.forEach((current: any, i: number) => {
      if (i <= currentNum) {
        const currentWidth = document.getElementById(`inizTagItem${current.key}`)?.clientWidth || 0;
        jumpWidth = jumpWidth + currentWidth;
      }
      if (i == currentNum) {
        nowCurrentWidth = document.getElementById(`inizTagItem${current.key}`)?.clientWidth || 0;
      }
    });

    if (elTagViewContainer) {
      if (jumpWidth < tagViewWidth) {
        elTagViewContainer.scrollLeft = 0;
        if (scrollWidth > tagViewWidth) {
          $isShowUp(false);
          $isShowNext(true);
        } else {
          $isShowUp(false);
          $isShowNext(false);
        }
        return;
      }

      if (jumpWidth > tagViewWidth && jumpWidth < scrollWidth) {
        const bl = Math.floor(jumpWidth / tagViewWidth);
        const trueJumWidth = bl * tagViewWidth;
        $isShowUp(true);
        if (scrollWidth - trueJumWidth >= tagViewWidth) {
          if (jumpWidth - trueJumWidth > nowCurrentWidth) {
            elTagViewContainer.scrollLeft = trueJumWidth;
          } else {
            elTagViewContainer.scrollLeft = trueJumWidth - nowCurrentWidth;
          }
          $isShowNext(true);
        } else {
          elTagViewContainer.scrollLeft = scrollWidth;
          $isShowNext(false);
        }
        return;
      } else {
        $isShowUp(true);
        $isShowNext(false);
        singleTimeOut(() => {
          elTagViewContainer.scrollLeft = jumpWidth;
        }, 0, 'inbiz-tab-tagEnd')
      }
    }
  };

  const jumpStart = () => {
    const elViewScroll = document.getElementById('inbiz-tag-view-scroll');
    const elTagViewContainer = document.getElementById('inbiz-tags-view-container');
    const scrollWidth = elViewScroll?.clientWidth || 0;
    const tagViewWidth = elTagViewContainer?.clientWidth || 0;
    if (elTagViewContainer) {
      $isShowUp(false);
      if (scrollWidth > tagViewWidth) {
        $isShowNext(true);
      } else {
        $isShowNext(false);
      }
      elTagViewContainer.scrollLeft = 0;
    }
  };

  // 下拉操作Item
  const menuAction = [
    {
      label: (
        <span>
          <TextWidget>TagsView.closeTag</TextWidget>
        </span>
      ),
      key: ACTION_NAME.CURRENT,
      disabled: !currentMenu || currentMenu == defaultIndexMenu.key || menuData.length == 1,
    },
    {
      label: (
        <span>
          <TextWidget>TagsView.closeOtherTag</TextWidget>
        </span>
      ),
      key: ACTION_NAME.OTHER,
      disabled: !currentMenu || menuData.length == 1,
    },
    {
      label: (
        <span>
          <TextWidget>TagsView.closeAllTag</TextWidget>
        </span>
      ),
      key: ACTION_NAME.ALL,
      disabled: !currentMenu || menuData.length == 1,
    },
  ];

  const menu = (
    <Menu
      onClick={changeRouter}
      selectedKeys={[currentMenu]}
      items={[
        ...menuAction,
        // {
        //   type: 'divider',
        // },
        // ...menuData.map((item) => {
        //   return {
        //     ...item,
        //     label: (
        //       <span title={getMessage(item.label)}>
        //         <TextWidget>{item.label}</TextWidget>
        //       </span>
        //     ),
        //   };
        // }),
      ]}
    />
  );


  const api = extendApi(
    (
      _events: any,
    ) => {
      return {
        refreshTag: (key?: string) => {
          if (!key) {
            aliveController.refresh(currentMenu || '');
            return
          }
          aliveController.refresh(key || '');
        },
        closeTag: (key?: string) => {
          if (!key) {
            closeByKey(currentMenu)
            return
          }
          closeByKey(key)
        }
      };
    },
  );

  useImperativeHandle(
    ref,
    () => ({
      ...api(configEvents)
    }));

  return (
    <div
      {...other}
      className={`${styles['inbiz-tags-view']}`}
      style={{
        backgroundColor: defaultBg,
      }}
      id={'inbiz-tags-view'}
    >
      {isShowUp && (
        <div className={styles['inbiz-tags-view-btn-box']}>
          <InbizIcon
            className={styles['inbiz-tags-view-btn']}
            type="icon-ic-zuofan"
            onClick={() => {
              const eleScroll = document.getElementById('inbiz-tag-view-scroll');
              const eleScrollContainer = document.getElementById('inbiz-tags-view-container');
              const scrollLeft = eleScrollContainer?.scrollLeft || 0;
              const scrollWidth = eleScroll?.clientWidth || 0;
              const tagViewWidth = eleScrollContainer?.clientWidth || 0;
              let left = scrollLeft - tagViewWidth;
              if (left < 0) {
                $isShowUp(false);
                left = 0;
              }
              if (eleScrollContainer) {
                if (scrollWidth > tagViewWidth) {
                  $isShowNext(true);
                }
                var timer = setTimeout(() => {
                  eleScrollContainer.scrollLeft = left;
                  clearTimeout(timer);
                }, 0);
              }
            }}
          />
        </div>
      )}

      <SortableList axis="xy" lockAxis="x" onSortEnd={onSortEnd} >
        {menuData.map((item, index) => {
          const isSelect = currentMenu == item.key;
          const isDefault = defaultIndexMenu.key == item.key;
          const hideLine = currentIndex != index && currentIndex != index - 1 && index != 0 && !isSelect;
          return (
            <SortableItem
              key={`item-${index}`}
              index={index} value={index} collection={item}>
              <li
                className={`${styles['inbiz-tags-view-li']} ${isSelect ? styles.active : ''}`}
                id={`inizTagItem${item.key}`}
                style={{
                  backgroundColor: isSelect ? selectBg : '',
                }}
              >

                {/* // 不显示'|'的条件 1.当前选中; 2.选中前面一个; 3.第一个 */}
                {hideLine && <span className={styles['inbiz-tags-view-Interval']}>|</span>}

                <span title={getMessage(item.label)} className={styles['inbiz-tags-view-tagname']}>
                  <TextWidget>{item.label}</TextWidget>
                </span>
                {isSelect && isRefresh && (
                  <InbizIcon
                    className={styles['inbiz-tags-view-icon']}
                    style={{ marginRight: isDefault ? 0 : 8 }}
                    onMouseDown={(e: MouseEvent) => {
                      e.preventDefault();
                      e.stopPropagation();
                      aliveController.refresh(item.key || '');
                    }}
                    type="icon-ic-shuaxin"
                  />
                )}
                {!isDefault && (
                  <InbizIcon
                    className={styles['inbiz-tags-view-icon']}
                    onMouseDown={(e: MouseEvent) => handleClose(item, e)}
                    type="icon-ic-close-bold"
                  />
                )}
              </li>
            </SortableItem>
          );
        })}
      </SortableList>
      {isShowNext && (
        <div className={styles['inbiz-tags-view-btn-box']} style={{ marginRight: 0 }}>
          <InbizIcon
            className={styles['inbiz-tags-view-btn']}
            type="icon-ic-youfan"
            onClick={() => {
              const eleScroll = document.getElementById('inbiz-tag-view-scroll');
              const eleScrollContainer = document.getElementById('inbiz-tags-view-container');
              const tagViewWidth = eleScrollContainer?.clientWidth || 0;
              const scrollWidth = eleScroll?.clientWidth || 0;
              const scrollLeft = eleScrollContainer?.scrollLeft || tagViewWidth;
              let left = scrollLeft + tagViewWidth;
              if (eleScrollContainer) {
                if (scrollWidth > tagViewWidth) {
                  $isShowUp(true);
                }
                if (left >= scrollWidth) {
                  $isShowNext(false);
                }
                var timer = setTimeout(() => {
                  eleScrollContainer.scrollLeft = left;
                  clearTimeout(timer);
                }, 0, 'inbiz-tag-next');
              }
            }}
          />
        </div>
      )}
      <Dropdown overlay={menu} trigger={['click']} overlayClassName={'tagsview-tool'}>
        <div className={styles['inbiz-tags-view-tool']} title={getMessage('TagsView.more')}>
          <InbizIcon className={styles['inbiz-tags-view-tool-btn']} type="icon-more1" />
        </div>
      </Dropdown>
    </div>
  );
}, { forwardRef: true });
export default TagsView;
